// Created: Dec 11, 2014
//
// Author: wjinwen.1988@gmail.com

#ifndef CHI_MUTEX_H
#define CHI_MUTEX_H

#include <assert.h>
#include <pthread.h>

namespace chi {
class MutexLock {
 public:
  MutexLock() {
    int ret = pthread_mutex_init(&mutex_, NULL);
    assert(ret == 0); (void) ret;
  }

  ~MutexLock() {
    int ret = pthread_mutex_destroy(&mutex_);
    assert(ret == 0); (void) ret;
  }

  MutexLock(const MutexLock&) = delete;
  void operator=(const MutexLock&) = delete;

  void Lock() { pthread_mutex_lock(&mutex_); }
  void Unlock() { pthread_mutex_unlock(&mutex_); }
  pthread_mutex_t* mutex() { return &mutex_; }

 private:
  pthread_mutex_t mutex_;
};

class MutexLockGuard {
 public:
  explicit MutexLockGuard(MutexLock& mutex)
    : mutex_(mutex) {
    mutex_.Lock();
  }

  ~MutexLockGuard() { mutex_.Unlock(); }

  MutexLockGuard(const MutexLockGuard&) = delete;
  void operator=(const MutexLockGuard&) = delete;

 private:
  MutexLock& mutex_;
};

}  // namespace chi

#endif 
